"""KIEL2 data format
Copyright (c) 2011 Christian T. Steigies <steigies@physik.uni-kiel.de>

This module offers functions to read NM data in ASCII format as used in KIEL
and return data in the format as used by NMDB."""

__author__ = "Christian T. Steigies <steigies@physik.uni-kiel.de>"
__license__ = "GPL License"

import os
import sys
import datetime
# monthrange, isleap
import calendar

# http://www.scipy.org/Tentative_NumPy_Tutorial#head-926a6c9b68b752eed8a330636c41829e6358b1d3
from numpy import * # python-numpy


#import nmdb
from nmdb.station.station_class import station, CheckData, CheckPressure

from nmdb.nm64.kiel2 import kiel2 as kiel2bin
from nmdb.editor.Median import Median

#from tools.datetime import YY

kiel_station = ["kiel", "kiel2"]

## --------------------------------------------------------------------------
def corrected_for_pressure(uncorrected, pressure_mbar):
    from math import exp
    
    p0 = 1006.7

    corrected = uncorrected * exp(0.00721*(pressure_mbar-p0))

    return corrected


def corrected_for_efficiency(uncorrected, pressure_mbar):
    return uncorrected

## --------------------------------------------------------------------------
class mystation(station):
    def __init__(self, name, mode, year, month, day=0):
        """read one day of station data"""

        self.mode = mode
        
        modes = ["1m", "1h", "1m-rt", "1h-rt", "rt", "ori", "rev"]
        if not (self.mode in modes):
            print "INVALID MODE:", self.mode
            sys.exit(1)

        station.__init__(self, name, year, month)

        if day == 0:
            day_min = 1
            (dummy, day_max) = calendar.monthrange(year,month) # determine number of days in the month
        else:
            day_min = day_max = day
        for day in range(day_min,day_max+1):
            for hour in range(0,24):
                if (self.mode == "ori" or self.mode == "1m-rt" or self.mode == "rt"):
                    """real-time high resolution data, write to ori """
                    #print "ori"
                    self.__read_1m(name, year, month, day, hour)
                elif (self.mode == "rev" or self.mode == "1m"):
                    """checked high resolution data, if it already exists in NMDB write to rev, new data to ori"""
                    #print "rev"
                    #pass # use upload_rev for this
                    self.__read_1m(name, year, month)
                elif (self.mode =="1h-checked"):
                    """checked 1h data"""
                    #print "1h"
                    pass # use upload_rev for this
                #self.__read_1h(name, year)
                elif (self.mode =="1h"):
                    """real-time 1h data"""
                    #print "1h rt"
                    self.__read_1h_rt(name)
                else:
                    print "no valid mode:", self.mode
                    sys.exit(1)
            
## --------------------------------------------------------------------------
    def __read_1m(self, name, year, month, day, hour):
        """read 1hour of data from Alcala registration system"""
        
        BIN = kiel2bin(name, year, month, day, hour)

        k = 18
        n0 = [30220, 35780, 36960, 37362, 37020, 31690,
              32550, 36785, 38000, 37284, 36826, 32270,
              32200, 37003, 37685, 37910, 37125, 31030]
        e0 = [1.]*k

        for minute in range(0,60):
            try:
                row = BIN._value(minute)
                ch = row[0:18] # 18 channels in counts per minute
                p = row[18]/100. # p in mbar
                nt = ch
                
                (summa, ne, et) = Median(k, n0, e0, nt)
                
                uc = summa
                cp = corrected_for_pressure(uc, p)
                ce = corrected_for_efficiency(cp, p)
                #print "uncorr: %i corr_p: %i corr_e: %i p_mbar: %8.3f" %(uc, cp, ce, p)
            
                if 0:
                    print "nt", nt, "sum:", sum(nt)
                    print "ne", ne, "sum:", sum(ne)
                    print "et", et
                            
                data = [datetime.datetime(year, month, day, hour, minute, 0), uc, p, cp]
                #print data
                self._c.execute('''INSERT INTO data VALUES (?, ?, ?, ?)''', data)
            except TypeError:
                    #print "no data for", year, month, day, hour, minute, row
                    pass
            
## --------------------------------------------------------------------------
    def raw(self, year=2000, month=1, day=1, hour=0, minute=0):
        """return raw values from NMDA"""
        dt = self.dt

        return dt, corr_p, corr_e, uncorr, press

## --------------------------------------------------------------------------
    def value(self, year=2000, month=1, day=1, hour=0, minute=0, mode="processed"):
        """convert values into NMDB format:
        counts are already given as counts per second
        CheckData|Pressure with optional range
        Check* returns NULL if input == 0 or out of range"""
        
        try:
            (utc, u, p, c) = self._value(year, month, day, hour, minute)
        except TypeError:
            return None

        if mode == "raw":
            uncorr = int(u)
            p_mbar = int(p)
            corr_p = int(c)
        elif mode == "processed":
            if self.mode == "ori": # convert from cts/min to cts/sec
                uncorr = CheckData(u/60.)
                p_mbar = CheckPressure(p)
                corr_p = CheckData(c/60.)
            elif self.mode == "1h":  # convert from cts/h/100 to cts/sec
                uncorr = u*100./3600.
                p_mbar = p
                corr_p = c*100/3600.
            else:
                raise ValueError # illegal self.mode

        else:
            raise ValueError # illegal mode

        corr_e = corr_p
        
        return (utc, uncorr, p_mbar, corr_p, corr_e)

    
## --------------------------------------------------------------------------
if __name__=="__main__":
    print "This is the kiel2 module."
